#include <iostream>
#include <pthread.h>
#include "BlockQueue.hpp"
#include <unistd.h>
#include "Task.hpp"

// 单生产和单消费者

// 枷锁是为了保护临界资源x,y
pthread_mutex_t Plock = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;

// 任务形式一
void *consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    while (true)
    {
        {
            sleep(10);
            char* buffer = new char[128];
            pthread_getname_np(pthread_self(), buffer, 128);
            Task t = bq->Pop();
            t.Excute();
            std::cout << buffer << "消费了一个任务: " << t.X() << "+" << t.Y() << "=" << t.Result() << std::endl;
        }
    }
}

int x = 1, y = 1;
void *product(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    while (true)
    {
        sleep(1);
        pthread_mutex_lock(&Plock);
        {
            char buffer[128];
            pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
            Task task(x, y);
            bq->Equeue(task);
            std::cout << buffer << "生产了一个任务: " << x << "+" << y << "=?" << std::endl;
            x++, y++;
        }
        pthread_mutex_unlock(&Plock);
    }
}

// 任务形式二
// void *consumer(void* args)
//{
//    BlockQueue<task_t>* bq = static_cast<BlockQueue<task_t>*>(args);
//    while (true)
//    {
//        task_t task = bq->Pop();
//        task();
//        std::cout << "消费了一个任务: " << std::endl;
//    }
//    return nullptr;
//}
//
// void *product(void* args)
//{
//    BlockQueue<task_t>* bq = static_cast<BlockQueue<task_t>*>(args);
//    while (true)
//    {
//        sleep(1);
//        bq->Equeue(Download);
//        std::cout << "生产了一个任务: " << std::endl;
//    }
//    return nullptr;
//}

// 消费者要执行的任务
// void *consumer(void *args)
//{
//    // 从阻塞队列中拿取数据
//    BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//    while (true)
//    {
//        int data = bq->Pop();
//        std::cout << "消费了一个数据: " << data << std::endl;
//    }
//    return nullptr;
//}
//
//// 生产者要执行的任务
// void *product(void *args)
//{
//     int num = 10;
//     // 往阻塞队列中push数据
//     BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//     while (true)
//     {
//         sleep(1);
//         bq->Equeue(num++);
//         std::cout << "生产了一个数据: " << num << std::endl;
//     }
//     return nullptr;
// }

int main()
{
    // 先申请一个阻塞队列
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    // BlockQueue<task_t> *bq = new BlockQueue<task_t>();

    // 创建生产者和消费者-线程
    pthread_t c[2], p[3];

    pthread_create(&c[0], nullptr, consumer, bq);
    pthread_setname_np(c[0], "threadc-1");

    pthread_create(&c[1], nullptr, consumer, bq);
    pthread_setname_np(c[1], "threadc-2");

    pthread_create(&p[0], nullptr, product, bq);
    pthread_setname_np(p[0], "threadp-1");

    pthread_create(&p[1], nullptr, product, bq);
    pthread_setname_np(p[1], "threadp-2");

    pthread_create(&p[2], nullptr, product, bq);
    pthread_setname_np(p[2], "threadp-3");

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);

    return 0;
}